/*
 * Exploder
 * 
 * Tero Pyylampi (218437), Jussi Tuurinkoski (211594)
 *
 * Abstract base class for all the physic objects in the game
 */

#ifndef GAMEPHYSICOBJECT_H
#define GAMEPHYSICOBJECT_H

#include "../GameObject.h"
#include "../../../Common.h"

#include "Box2D/Box2D.h"
#include "cocos2d.h"

// available "advanced" objects
enum AdvancedObjectType { BOX_USING_TRIANGLES, BOX_USING_BOXES };

class GamePhysicObject : public GameObject {
public:
	// default constructor
	GamePhysicObject( b2World *world );
	// default destructor
	virtual ~GamePhysicObject();

	// default update function
	virtual void update( cocos2d::ccTime dt ) = 0;

	// object takes damage as a result of a collisiong
	virtual void takeDamage( float damage, b2Body *bodyTakingDamage );
	// set new color for object sprites
	virtual void setObjectColor( cocos2d::ccColor3B c );

	// get the physics objects
	std::vector< b2Body* > *getBodyObjects();

	// get the main type of the object
	virtual PhysicObjectItems getObjectType() = 0;

	// calculate length between my position and given point
	float calculateDistanceTo( b2Vec2 worldPoint );
	// check whether this object is asleep
	bool currentlyAsleep();
	
	// check whether this object owns this specific body
	bool ownerOfBody( b2Body *body );

	// get absolute screen position of the sprite
	virtual cocos2d::CCPoint getObjectScreenPosition();

protected:
	// pointer to the physics world
	b2World *mGameWorld;
	// array of physic bodies included in this specific physic object
	std::vector< b2Body* > *mBodies;

	// helper functions for creating physics bodies

	// properties used as a parameter when creating bodies
	struct ObjectProperties {
		ObjectProperties( float d, float f, float r ) :
			density( d ), friction( f ), restitution( r ) {}
		float density;
		float friction;
		float restitution;
	};

	// create a single triangle with given width & height
	enum TriangleData{ BOTTOM_LEFT, BOTTOM_RIGHT, TOP_LEFT, TOP_RIGHT };
	b2Body *createTriangle( bool kinematic, float width, float height, float cornerX, float cornerY, ObjectProperties &properties, TriangleData data );
	// create a single circle shaped object
	b2Body *createCircle( bool kinematic, float radius, float centerX, float centerY, ObjectProperties &properties );
	// create a single box shaped object with given width and height
	b2Body *createBox( bool kinematic, float width, float height, float centerX, float centerY, ObjectProperties &properties );
};

#endif